package com.lanhai.zhonglai.impl;


import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import com.google.gson.Gson;
import com.lanhai.zhonglai.beans.StationDataBean;
import com.lanhai.zhonglai.beans.StationLockBean;
import com.lanhai.zhonglai.utils.DmdUtils;
import com.lanhai.zhonglai.utils.StationTeamUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.lanhai.zhonglai.MsgCore;
import com.lanhai.zhonglai.beans.AgvBean;
import com.lanhai.zhonglai.beans.AgvDataBean;
import com.lanhai.zhonglai.beans.AgvMountBean;
import com.lanhai.zhonglai.beans.StationBean;
import com.lanhai.zhonglai.beans.DotBean;
import com.lanhai.zhonglai.dao.StationGroupDao;
import com.lanhai.zhonglai.dao.RoadDao;
import com.lanhai.zhonglai.dispatch.AgvCmdMap;
import com.lanhai.zhonglai.dispatch.QrLeaveCheck;
import com.lanhai.zhonglai.dispatch.StationCmdMap;
import com.lanhai.zhonglai.enums.AgvCurrentTransEnum;
import com.lanhai.zhonglai.enums.AgvMountTypeEnum;
import com.lanhai.zhonglai.enums.CacheStationEnumType;
import com.lanhai.zhonglai.enums.TransDirectionEnum;
import com.lanhai.zhonglai.interfaces.IAgv;
import com.lanhai.zhonglai.interfaces.IAgvEvent;
import com.lanhai.zhonglai.interfaces.IAgvMount;
import com.lanhai.zhonglai.interfaces.ICmdLog;
import com.lanhai.zhonglai.interfaces.IStation;
import com.lanhai.zhonglai.interfaces.IDot;
import com.lanhai.zhonglai.interfaces.IDotEvent;
import com.lanhai.zhonglai.interfaces.IPower;
import com.lanhai.zhonglai.interfaces.IRoad;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

@Service
public class DotEventImpl implements IDotEvent {
    @Autowired
    IAgv iAgv;

    @Autowired
    IAgvMount iAgvMount;

    @Autowired
    IStation iStation;

    @Autowired
    IDot iDot;

    @Autowired
    IAgvEvent iAgvEvent;

    @Autowired
    IPower iPower;

    @Autowired
    IRoad iRoad;

    @Autowired
    ICmdLog iCmdLog;


    @Autowired
    AgvCmdMap agvCmdMap;

    @Autowired
    QrLeaveCheck qrCheck;

    @Autowired
    private JedisPool jedisPool;

    @Autowired
    StationTeamUtils teamUtils;

    @Autowired
    private DmdUtils dmdUtils;


    /**
     * 只处理一次
     */
    @Override
    public void arrivedDecide(AgvBean agv, DotBean dot, AgvDataBean data) {
        // 异常装料状态
        if (data.getMountType() == AgvMountTypeEnum.Error) {
            // 错误的装卸状态，不处理
            MsgCore.sendMsg(agv.getAgvId(), "花篮数量异常，暂停");
            return;
        }

        // 决策点选择
        switch (dot.getDotno()) {
            case 350:
                //制绒上料判断
                d350(agv, data, dot);
                break;
            case 363:
                //只处理发料小车，充电或者去201
                p363(agv);
                break;
            case 366:
                //制绒下料
                d366(agv, data, dot);
                break;
            case 368:
                //判断POPAID上料
                d368(agv, data, dot);
                break;
            case 390:
                //空车去BOE下料或者451，有料去BOE上料
                d390(agv, data, dot);
                break;
            case 392:
                d392(agv, data, dot);
                break;
            case 397:
                d397(agv, data, dot);
                break;
            case 406:
                //扩散上料判断点
                d406(agv, data, dot);
                break;
            case 403:
                d403(agv, data, dot);
                break;
            case 425:
                //判断BSG，或者空车充电
                d425(agv, data, dot);
                break;
            case 437:
                //判断碱抛下料或者去366
                d437(agv, data, dot);
                break;
            case 451:
                //空车去393，否则去ALD湿法
                d451(agv, data, dot);
                break;
            case 475:
                //判断镀膜(正膜）
                d475(agv, data, dot);
                break;
            case 477:
                d477(agv, data, dot);
                break;
            case 478:
                //扩散上料机台选择
                d478(agv, data, dot);
                break;
            case 479:
                //退火上料选择
                d479(agv, data, dot);
                break;
            case 476:
                //丝网
                d476(agv, data, dot);
                break;
            case 518:
                d518(agv, data, dot);
            case 729:
                d729(agv, data, dot);
                break;
        }

    }

    /**
     * 充电桩
     */
    @Override
    public void arrivedPower(AgvBean agv, DotBean dot) {
        //

    }

    /**
     * 路由点 AGV自带路由优先
     */
    @Override
    public void arrivedRoute(AgvBean agv, DotBean dot) {
        if (dot.getDotno() == 362) {
            int target = 364;
            if (agv.getAgvId() == 19 || agv.getAgvId() == 20) {
                //发料小车
                target = 363;
            } else {
                //大车
                target = 364;
            }
            int road = iRoad.getNormalRoad(362, target);
            if (road > 0) {
                iAgvEvent.toRoad(agv, road);
            } else {
                MsgCore.sendMsg(agv.getAgvId(), String.format("缺少%d到%d的路线", 362, target));
            }
        } else {
            if (agv.getNextRoad() > 0) {
                int p = agv.getNextRoad();
                agv.setNextRoad(0);
                iAgv.saveCache(agv);
                iAgvEvent.toRoad(agv, p);
            } else {
                if (dot.getRouteRoad() > 0) {
                    iAgvEvent.toRoad(agv, dot.getRouteRoad());
                } else {
                    MsgCore.sendMsg(agv.getAgvId(), "点位数据不全");
                }
            }
        }
    }

    /**
     * 传输位
     */
    @Override
    public void arrivedTrans(AgvBean agv, DotBean dot) {
        // 记录点位信息
        iDot.setDotOfAgv(dot.getDotno(), agv.getAgvId());


        // 重置机台的传输状态（注意，到达传输工位，可能不是机台）
        StationBean station = iStation.getBeanByDot(dot.getDotno());
        if (station != null) {
            // 清理机台传输状态
            StationCmdMap.clearState(station.getDotno());

            //解锁充电桩
            iPower.unlockPowerByAgv(agv.getAgvId());

            // 锁定机台 并解锁其它点位
            iStation.lockStationOnTarget(dot.getDotno(), agv.getAgvId());

            agv.setSpecialline(station.getSpecialline());

            if (station.isUpTrans() == false) {
                agv.setUpHasTrans(true);
            }
            if (station.isDownTrans() == false) {
                // 下层不可传=下层已经传输完成
                agv.setDownHasTrans(true);
            }
            agv.setNextRoad(0);
            agv.setToHC(false);
            agv.setFromHC(false);
            agv.setFinishTrans(false);
            agv.setBothTrans(false);
            agv.setFakeLeave(false);
            agv.setNotClear(false);
            agv.setCurrentTrans(AgvCurrentTransEnum.None);
            iAgv.saveCache(agv);
        }

    }

    @Override
    public void arrivedWait(AgvBean agv, AgvDataBean data, DotBean dot) {
        //不管怎么样先添加小车与待命点的缓存 -> 防止人为原因摇车到待命点 后续小车再过来
        dmdUtils.lockDmd(agv.getAgvId() + "", dot.getDotno() + "");

        //制绒待命点空车去制绒下料
        if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
            MsgCore.sendMsg(agv.getAgvId(), "制绒下料无机台可用，等待");
            StationGroupDao gbean = iStation.fetchNextOutStation(dot.getDotno(), agv.getAgvId(), "制绒下料", true);
            if (gbean != null) {
                //去366
                toDot(agv, dot.getDotno(), 366);
                MsgCore.sendMsg(agv.getAgvId(), "去往制绒下料");
            }
        } else if (data.getMountType() == AgvMountTypeEnum.UpFullAndDownEmpty) {
            MsgCore.sendMsg(agv.getAgvId(), "制绒上料无机台可用，等待");
            //去制绒上料
            boolean flag = findStationWithNoSpecial(dot, agv, "制绒上料", true, TransDirectionEnum.OnlyIn);

            if (flag) {
                //清理待命点缓存
                dmdUtils.clearlockDmd(agv.getAgvId() + "", dot.getDotno() + "");
                //clearlockDmd(agv.getAgvId() + "", dot.getDotno() + "");
                MsgCore.sendMsg(agv.getAgvId(), "去往制绒上料号机台");
            }

            //制绒待命点空车去制绒上料
            //  没有待命点
            // 查看是哪个区域的待命点  --> 现在还有制绒上料有待命点


            //查看是否有合适机台

//            boolean checkzrsEmpty = checkZrsEmpty();
//
//            //查看制绒上料机台是否有小车
//            boolean checkNextProcess = iStation.hasEmpty("制绒上料");
//
//            if (!checkNextProcess || checkzrsEmpty) {
//                return;
//            }
//
//            Jedis jd = jedisPool.getResource();
//            Gson gson = new Gson();
//
//            String key = "stationlocklist";
//
//            try {
//                //查看机台是否被锁
//                String[] checkdotid = {"7", "1"};
//                MsgCore.sendMsg(agv.getAgvId(), "寻找制绒上料满足条件机台");
//                for (String check : checkdotid) {
//                    if (!jd.hexists(key, check)) {
//                        //去往机台做处理
//                        toDot(agv, dot.getDotno(), Integer.parseInt(check)); // ->去制绒上料
//                        // 锁机台
//                        StationLockBean dao = new StationLockBean();
//                        // 强制锁
//                        dao.setAgvid(agv.getAgvId());
//                        dao.setIslock(true);
//                        dao.setLasttime(System.currentTimeMillis());
//                        String json = gson.toJson(dao);
//                        jd.hset(key, "" + check, json);
//                        //jd.close();
//
//                        return;
//                    }
//                }
//            } finally {
//                jd.close();
//            }

        }
    }

    /**
     * 能进此方法肯定是传输完成 AGV的目标路线由对接机台点位设置
     */
    @Override
    public void arrivedQR(AgvBean agv, DotBean dot) {

        // 传输工位点位解锁
        int transdot = iDot.getTransDotNo(dot.getDotno());
        if (transdot > 0) {
            iDot.setDotOfAgv(transdot, 0);
            // 机台解锁 。只能解自己锁定的机台
            iStation.unlockStationForDot(transdot, agv.getAgvId());
        }

        agv.setTransing(false);
        agv.setFinishTrans(false);
        agv.setUpHasTrans(false);
        agv.setDownHasTrans(false);
        iAgv.saveCache(agv);

        //充电桩的不会进来

        if (dot.getDotno() > 250 && dot.getDotno() < 300
                && dot.getDotno() != 275 && dot.getDotno() != 277
                && dot.getDotno() != 253 && dot.getDotno() != 255) {
            //从二维码开始的路线
            if (agv.getNextRoad() > 0) {
                iAgvEvent.toRoad(agv, agv.getNextRoad());
            } else {
                if (dot.getRouteRoad() > 0) {
                    // 小车跑路
                    iAgvEvent.toRoad(agv, dot.getRouteRoad());
                } else {
                    MsgCore.sendMsg(agv.getAgvId(), "数据错误，缺少目标路线");
                }
            }
        } else {
            if (dot.getRouteRoad() > 0) {
                // 小车跑路
                iAgvEvent.toRoad(agv, dot.getRouteRoad());
            } else {
                MsgCore.sendMsg(agv.getAgvId(), "数据错误，缺少目标路线");
            }
        }


    }

    /**
     * 到达普通点位
     */
    @Override
    public void arrivedNormal(AgvBean agv, DotBean dot) {

        //logger.error( "点位"+dot.getDotno()+" 是普通点位， 没有事件.对应AgV="+agv.getAgvId());
    }

    /**
     * 电量判断位
     */
    @Override
    public void arrivedPowerCheck(AgvBean agv, AgvDataBean data, DotBean dot) {
        if (dot.getDotno() == 364) {
            p364(agv, dot);
        } else if (dot.getDotno() == 393) {
            p393(agv, data);
        } else if (dot.getDotno() == 452) {
            p452(agv, data);
        } else if (dot.getDotno() == 363) {
            p363(agv);
        }

    }

    @Override
    public void arrivedQRWithNoTrans(AgvBean agv, DotBean dot, AgvMountBean agvmount, int transDotno) {
        if (agvmount.getMountType() == AgvMountTypeEnum.Error) {
            // 错误的装卸情况，比如上X下空，上满下X，不处理
            MsgCore.sendMsg(agv.getAgvId(), "花篮数量异常，暂停");
            return;
        }
        //再次重置
        agv.setTransing(false);
        agv.setFinishTrans(false);
        agv.setUpHasTrans(false);
        agv.setDownHasTrans(false);
        iAgv.saveCache(agv);


        // 二维码的点位处理
        if (transDotno > 301 && transDotno < 350) {
            //处理充电桩,只做释放
            iPower.unlockPowerNotice(transDotno);
            if (dot.getRouteRoad() > 0) {
                iAgvEvent.toRoad(agv, dot.getRouteRoad());
            } else {
                MsgCore.sendMsg(agv.getAgvId(), dot.getDotno() + "缺少路线");
            }
        } else if (transDotno > 250 && transDotno < 300) {
            //缓存机，非空不准走
            if (agvmount.getMountType() != AgvMountTypeEnum.AllEmpty) {
                // 错误的装卸情况，比如上X下空，上满下X，不处理
                MsgCore.sendMsg(agv.getAgvId(), "非空车不准移动");
                return;
            }
            if (dot.getRouteRoad() > 0) {
                iAgvEvent.toRoad(agv, dot.getRouteRoad());
            } else {
                MsgCore.sendMsg(agv.getAgvId(), dot.getDotno() + "缺少路线");
            }
        } else {
            qrCheck.check(agv, dot, agvmount, transDotno);
        }

    }


    // ********** 决策位判断方法 注意，大部分看着很像感觉能抽象，其实有细微差别。代码求稳！ *****************


    /**
     * 只做点与点的路由，不做agv修改
     *
     * @param agv
     * @param startDotno
     * @param routeDotno
     */
    void toDot(AgvBean agv, int startDotno, int routeDotno) {
        int road = iRoad.getNormalRoad(startDotno, routeDotno);
        if (road > 0) {
            iAgvEvent.toRoad(agv, road);
        } else {
            // 没有路线，数据上的错误 -1
            MsgCore.sendMsg(agv.getAgvId(), String.format("程序异常，请检查%d到%d有没有路线", startDotno, routeDotno));
        }
    }

    /**
     * 找无线别的机台
     *
     * @param startDot
     * @param agv
     * @param process
     * @param wait
     */
    boolean findStationWithNoSpecial(DotBean startDot, AgvBean agv, String process, boolean wait, TransDirectionEnum transType) {
        // 已经存在的
        StationGroupDao gbean = null;
        if (transType == TransDirectionEnum.OnlyOut) {
            gbean = iStation.fetchNextOutStation(startDot.getDotno(), agv.getAgvId(), process, true);
        } else {
            gbean = iStation.fetchNextInStation(startDot.getDotno(), agv.getAgvId(), process, 0, true);
        }
        if (gbean == null) {
            //没找到
            if (wait) {
                // 没有机台，需要等下一个周期
                return false;
            } else {
                //走路由
                if (startDot.getRouteRoad() > 0) {
                    agv.setNextRoad(0);
                    agv.setNextProcess("去下一道工序");
                    agv.setNexttStationName("");
                    iAgv.saveCache(agv);
                    iAgvEvent.toRoad(agv, startDot.getRouteRoad());
                    return true;
                } else {
                    return false;
                }
            }
        } else {
            //有机台
            RoadDao roadDao = iRoad.getTransRoad(startDot.getDotno(), gbean.getDotno());
            if (roadDao != null && roadDao.getId() > 0) {
                decideAgvToRoad(agv, process, roadDao.getId(), gbean.getStationname(), gbean.getDotno());
            } else {
                // 没有路线，数据上的错误 -1
                MsgCore.sendMsg(agv.getAgvId(), String.format("程序异常，请检查%d到%d有没有路线", startDot.getDotno(), gbean.getDotno()));
            }
            return true;
        }
    }


    boolean findBSGStation(DotBean startDot, AgvBean agv) {
        // 已经存在的

        StationGroupDao gbean = iStation.fetchNextBSGOutStation(startDot.getDotno(), agv.getAgvId(), "BSG", 7);

        if (gbean == null) {
            //没找到
            return false;
        } else {
            //有机台
            RoadDao roadDao = iRoad.getTransRoad(startDot.getDotno(), gbean.getDotno());
            if (roadDao != null && roadDao.getId() > 0) {
                decideAgvToRoad(agv, "BSG", roadDao.getId(), gbean.getStationname(), gbean.getDotno());
            } else {
                // 没有路线，数据上的错误 -1
                MsgCore.sendMsg(agv.getAgvId(), String.format("程序异常，请检查%d到%d有没有路线", startDot.getDotno(), gbean.getDotno()));
            }
            return true;
        }
    }

    boolean findStationWithNoSpecial(DotBean startDot, AgvBean agv, List<String> processlist, boolean wait, TransDirectionEnum transType) {
        // 已经存在的
        StationGroupDao gbean = null;
        // 上料的选择 (注意，有线别）
        if (transType == TransDirectionEnum.OnlyOut) {
            gbean = iStation.fetchNextOutStation(startDot.getDotno(), agv.getAgvId(), processlist, true);
        } else {
            gbean = iStation.fetchNextInStation(startDot.getDotno(), agv.getAgvId(), processlist.get(0), 0, true);
        }
        if (gbean == null) {
            //没找到
            if (wait) {
                return false;
            } else {
                //走路由
                if (startDot.getRouteRoad() > 0) {
                    agv.setNextRoad(0);
                    agv.setNextProcess("去下一道工序");
                    agv.setNexttStationName("");
                    iAgv.saveCache(agv);
                    iAgvEvent.toRoad(agv, startDot.getRouteRoad());
                    return true;
                } else {
                    return false;
                }
            }
        } else {
            //有机台
            RoadDao roadDao = iRoad.getTransRoad(startDot.getDotno(), gbean.getDotno());
            if (roadDao != null && roadDao.getId() > 0) {
                decideAgvToRoad(agv, gbean.getProcess(), roadDao.getId(), gbean.getStationname(), gbean.getDotno());

            } else {
                // 没有路线，数据上的错误 -1
                MsgCore.sendMsg(agv.getAgvId(), String.format("程序异常，请检查%d到%d有没有路线", startDot.getDotno(), gbean.getDotno()));

            }
            return true;
        }
    }


    /**
     * 找有线别的机台(agv有料的情况）
     *
     * @param startDot
     * @param agv
     * @param process
     * @param specialline
     * @param transType
     */
    boolean findStation(DotBean startDot, AgvBean agv, String process, int specialline, TransDirectionEnum transType) {
        // 已经存在的
        StationGroupDao gbean = null;
        // 上料的选择 (注意，有线别）
        if (transType == TransDirectionEnum.OnlyOut) {
            gbean = iStation.fetchNextOutStation(startDot.getDotno(), agv.getAgvId(), process, true);
        } else {
            gbean = iStation.fetchNextInStation(startDot.getDotno(), agv.getAgvId(), process, specialline, true);
        }

        if (gbean == null) {
            // 没有机台，需要等下一个周期
            return false;
        } else {
            RoadDao roadDao = iRoad.getTransRoad(startDot.getDotno(), gbean.getDotno());
            if (roadDao != null && roadDao.getId() > 0) {
                decideAgvToRoad(agv, process, roadDao.getId(), gbean.getStationname(), gbean.getDotno());
                return true;
            } else {
                // 没有路线，数据上的错误 -1
                MsgCore.sendMsg(agv.getAgvId(), String.format("程序异常，请检查%d到%d有没有路线", startDot.getDotno(), gbean.getDotno()));
                return false;
            }
        }
    }


    /**
     * 去确定的目标机台
     *
     * @param agv
     * @param process
     * @param road
     * @param stationname
     * @param targetdotno
     */
    void decideAgvToRoad(AgvBean agv, String process, int road, String stationname, int targetdotno) {

        // 重置机台传输数据
        StationCmdMap.clearState(targetdotno);
        if (stationname != null && stationname.equals("") == false) {
            MsgCore.sendMsg(agv.getAgvId(), "目标机台:" + stationname);
        } else {
            MsgCore.sendMsg(agv.getAgvId(), "寻找下一道工序");
        }


        agv.setNextRoad(0);
        agv.setNextProcess(process);
        agv.setNexttStationName(stationname);
        agv.setFinishTrans(false);
        agv.setUpHasTrans(false);
        agv.setDownHasTrans(false);
        iAgv.saveCache(agv);

        iAgvEvent.toRoad(agv, road);
    }


    /**
     * 制绒上料决策点.如果是空车，就去364
     *
     * @param agv
     * @param data
     * @return
     */
    void d350(AgvBean agv, AgvDataBean data, DotBean dot) {
        if (agv.getAgvId() == 19 || agv.getAgvId() == 20) {
            //发料车,直接去363 ，走111
            iAgvEvent.toRoad(agv, 111);   //直走，不调用toDot
        } else {
            //普通车
            if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
                // 全空车
                boolean flag = iStation.findCache(CacheStationEnumType.ZRS, agv.getAgvId(), false, true);
                if (flag) {
                    toDot(agv, dot.getDotno(), CacheStationEnumType.ZRS.getDotno() - 1);
                } else {
                    MsgCore.sendMsg(agv.getAgvId(), "准备去制绒下料");
                    toDot(agv, dot.getDotno(), 364);
                }

            } else if (data.getMountType() == AgvMountTypeEnum.UpFullAndDownEmpty) {
                //如果是上满下空则去制绒上料，上料机台有小车在 则去待命点( 还需要判断上空花篮的状态 上空花篮优先级高于上料)

                //todo 现在先查看单机台的上空花篮状态(满足需求再说) 后续需要改为多机台
//                boolean checkzrsEmpty = checkZrsEmpty();
//
//                //查看制绒上料机台是否有小车
//                boolean checkNextProcess = iStation.hasEmpty("制绒上料");
//                //没有可用机台去待命点
//                if (checkNextProcess && !checkzrsEmpty) {
//
//
//
//                } else {
                boolean flag = findStationWithNoSpecial(dot, agv, "制绒上料", false, TransDirectionEnum.OnlyIn);
                if (flag == false) {
                    //找缓存机
                    boolean tocache = iStation.findCache(CacheStationEnumType.ZRS, agv.getAgvId(), true, true);
                    if (tocache) {
                        toDot(agv, dot.getDotno(), CacheStationEnumType.ZRS.getDotno() - 1);
                    } else {
                        //增量逻辑之前是寻找上料点  现在去往待命点

                        MsgCore.sendMsg(agv.getAgvId(), "寻找制绒上料待命点");
                        //查看是否有待命点
                        String dotid = dmdUtils.checkDmdbyZrs(agv.getAgvId());

                        //有待命点则去待命点
                        if (dotid != null) {
                            toDot(agv, dot.getDotno(), Integer.parseInt(dotid));
                            MsgCore.sendMsg(agv.getAgvId(), "去往制绒上料待命点：" + dotid);
                            //给待命点加锁
                            dmdUtils.lockDmd(agv.getAgvId() + "", dotid);
                        }

                        //MsgCore.sendMsg(agv.getAgvId(), "制绒上料没有可用的机台，等待中");
                    }
                }
                //}
            } else {
                MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息，无法与制绒上料对接");
            }
        }

    }


    //查看制绒上空花篮机台的情况  是否能让小车过去上料
    @Deprecated
    private boolean checkZrsEmpty() {
        Jedis resource = jedisPool.getResource();
        Gson gson = new Gson();
//        String zrsip = "10.11.34.34"; //制绒上空花篮的ip
//        String[] zrsline = {"3", "4"}; //制绒上空花篮的线别

        String[] check = {"StationDataBean:10.11.34.34_line:4", "StationDataBean:10.11.34.33_line:3",
                "StationDataBean:10.11.34.3_line:3", "StationDataBean:10.11.34.34_line:4"};

        boolean checkZrsEmpty = Arrays.stream(check).anyMatch(item -> {
            String s = resource.get(item);
            //没有缓存对象放行
            if (s.isEmpty()) {
                return true;
            }
            StationDataBean stationDataBean = gson.fromJson(s, StationDataBean.class);
            return stationDataBean.getBean().isAllowOut();
        });
        resource.close();

        return checkZrsEmpty;
    }

    /**
     * 判断制绒下料。如果没位子，去368
     *
     * @param agv
     * @param data
     */
    void d366(AgvBean agv, AgvDataBean data, DotBean dot) {
        if (data.getMountType() != AgvMountTypeEnum.AllEmpty) {
            // 不是空车，报错
            MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息，只允许空车在此处");
            return;
        }

		/*
		if(agv.getNextProcess()!=null&&agv.getNextProcess().equals("碱抛下料")) {
			//后段的车
			toDot(agv, 366, 368);
			return;
		}

		 //制绒没有的情况下，先考虑扩散下料(366-406)。扩散下料也没有的情况下，POAID
		//如果POPAID不可用，找碱抛。如果碱抛没有可用的（没有可用，不用锁），去BSG
		boolean go = findStationWithNoSpecial(dot, agv, "制绒下料", true, TransDirectionEnum.OnlyOut);
		if (go == false) {
			//制绒下料没可用机台，去406，找扩散出料
			//toDot(agv, 366, 406);
			//toDot(agv, 366, 368);
		}else {
			//制绒下料可用 do nothing
		}
		*/
        if (agv.getNextProcess() != null && agv.getNextProcess().equals("碱抛下料")) {
            //碱抛的空车直接去368
            toDot(agv, 366, 368);
            return;
        }

        boolean flag = findStationWithNoSpecial(dot, agv, "制绒下料", true, TransDirectionEnum.OnlyOut);
        if (flag == false) {
            MsgCore.sendMsg(agv.getAgvId(), "制绒下料没有可用的机台");
        }
    }

    /**
     * 只判断POPAID上料
     *
     * @param agv
     * @param data
     * @return
     */
    void d368(AgvBean agv, AgvDataBean data, DotBean dot) {

        if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
            boolean flag = findStationWithNoSpecial(dot, agv, "POPAID下料", false, TransDirectionEnum.OnlyOut);
            if (flag == false) {
                //没有可用机台，空车去479
                toDot(agv, dot.getDotno(), 479);
            }
            return;
        }
        if (data.getMountType() != AgvMountTypeEnum.UpEmptyAndDownFull) {
            // 不是上空下满
            MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息，无法给POPAID上料");
            return;
        }
        //碱抛下料离开机台时已经确定的popaid上料机台和缓存机。此处找不到机台只能等
        findStation(dot, agv, "POPAID上料", agv.getSpecialline(), TransDirectionEnum.OnlyIn);

    }

    /**
     * 去406,或者制绒下料缓存机
     *
     * @param agv
     * @param data
     * @return
     */
    void d478(AgvBean agv, AgvDataBean data, DotBean dot) {
        //制绒下料到扩散上料，去406点
        toDot(agv, dot.getDotno(), 406);

    }

    /**
     * 有料的车到这里前已经锁定了机台了，直接去机台。空车直接去下个站
     *
     * @param agv
     * @param data
     * @param dot
     * @return
     */
    void d425(AgvBean agv, AgvDataBean data, DotBean dot) {
        if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {

            //碱抛下料不享受充电桩
            if (agv.getNextProcess() != null && agv.getNextProcess().equals("碱抛下料")) {
                toDot(agv, dot.getDotno(), 450);
                return;
            }

            //充电桩选择
            if (data.getPower() < 60) {
                //充电
                if (iPower.agvToPower(425, agv)) {
                    return;
                }
            }

            //空车考虑的是出料,特例方法
            boolean flag = findBSGStation(dot, agv);
            if (flag == false) {
                //没有机台可用，去450
                agv.setNextProcess("制绒下料");
                iAgv.saveCache(agv);
                toDot(agv, dot.getDotno(), 450);
            }
            return;
        }
        if (data.getMountType() != AgvMountTypeEnum.UpEmptyAndDownFull) {
            MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息，请检查AGV是否人为移动");
            return;
        }
        //上空下满，给BSG上料
        boolean flag = findStation(dot, agv, "BSG", agv.getSpecialline(), TransDirectionEnum.OnlyIn);
        if (flag == false) {
            MsgCore.sendMsg(agv.getAgvId(), "没有可用的BSG机台");
        }
    }


    /**
     * 判断扩散
     *
     * @param agv
     * @param data
     * @param dot
     */
    void d406(AgvBean agv, AgvDataBean data, DotBean dot) {
        if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
            //退火下料的返空车，直接去366点，不参与此处的调度
            if (agv.getNextProcess() != null && agv.getNextProcess().equals("碱抛下料")) {
                // 去366点
                iAgvEvent.toRoad(agv, 168);
                return;
            }
            //空车，接扩散下料，没有就去bsg
            //1。找制绒下料缓存(出料模式
            boolean hasCache = iStation.findCache(CacheStationEnumType.ZRX, agv.getAgvId(), false, true);
            if (hasCache) {
                toDot(agv, 406, CacheStationEnumType.ZRX.getDotno() - 1);
                return;
            }
            //2。找扩散下料（出料模式）
            hasCache = iStation.findCache(CacheStationEnumType.KS, agv.getAgvId(), false, true);
            if (hasCache) {
                toDot(agv, 406, CacheStationEnumType.KS.getDotno() - 1);
                return;
            }

            boolean flag = findStationWithNoSpecial(dot, agv, "扩散下料", false, TransDirectionEnum.OnlyOut);
            if (flag == false) {
                //正式的去425
                toDot(agv, 406, 425);

                //测试： 去366等
                //iAgvEvent.toRoad(agv, 168);
            }
            return;
        } else if (data.getMountType() == AgvMountTypeEnum.UpEmptyAndDownFull) {
            //上空下满，不一定是扩散上料，一些异常存在，可能是碱抛下料。这里的判断不能省
            if (agv.getNextProcess() != null && (agv.getNextProcess().equals("扩散上料") || agv.getNextProcess().equals("制绒下料"))) {
                boolean flag = findStation(dot, agv, "扩散上料", agv.getSpecialline(), TransDirectionEnum.OnlyIn);
                if (flag == false) {
                    //没有可用机台，找缓存机
                    flag = iStation.findCache(CacheStationEnumType.ZRX, agv.getAgvId(), true, true);
                    if (flag == false) {
                        //没有缓存机用
                        MsgCore.sendMsg(agv.getAgvId(), "目标工序：扩散上料。暂无可用机台和缓存");
                    } else {
                        //去缓存机
                        toDot(agv, dot.getDotno(), CacheStationEnumType.ZRX.getDotno() - 1);
                    }
                }
            } else {
                //非扩散的工序，比发碱抛，去368,走159路
                iAgvEvent.toRoad(agv, 159);
            }


        } else {
            MsgCore.sendMsg(agv.getAgvId(), "请检查AGV的来源，装料信息不对AGV无法去下道工序：" + agv.getNextProcess());
        }
    }

    /**
     * 如果碱抛没有可用机台
     *
     * @param agv
     * @param data
     * @param dot
     */
    void d437(AgvBean agv, AgvDataBean data, DotBean dot) {
        if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
            if (agv.getNextProcess() != null && agv.getNextProcess().equals("BOE下料")) {
                //直接去392
                toDot(agv, dot.getDotno(), 392);
                return;
            }
			/*
			if(agv.getNextProcess()!=null&&agv.getNextProcess().equals("退火下料")) {
				//直接去479
				toDot(agv, dot.getDotno(), 479);
				return;
			}
			 */

            //不是BOE下料的车，电量充足，全部参与碱抛下料的操作
            //没有机台就去366

            //空车
			/*
			if(data.getPower()<60) {
				//电量不足，直接去350
				toDot(agv, dot.getDotno(), 350);
				return;
			}
			*/

            if (agv.getNextProcess() != null && agv.getNextProcess().equals("制绒下料")) {
                //直接去350
                toDot(agv, dot.getDotno(), 350);
                return;
            }

            agv.setNextProcess("碱抛下料");
            iAgv.saveCache(agv);
            String process = "碱抛下料";
            boolean flag = findStationWithNoSpecial(dot, agv, process, false, TransDirectionEnum.OnlyOut);
            if (flag == false) {
                //没有碱抛下料机台，去缓存机
                flag = iStation.findCache(CacheStationEnumType.TH, agv.getAgvId(), false, true);
                if (flag) {
                    //去缓存
                    toDot(agv, dot.getDotno(), CacheStationEnumType.TH.getDotno() - 1);
                    return;
                }
                flag = iStation.findCache(CacheStationEnumType.BSG, agv.getAgvId(), false, true);
                if (flag) {
                    //去缓存
                    toDot(agv, dot.getDotno(), CacheStationEnumType.BSG.getDotno() - 1);
                    return;
                }
                flag = iStation.findCache(CacheStationEnumType.JP, agv.getAgvId(), false, true);
                if (flag) {
                    //去缓存
                    toDot(agv, dot.getDotno(), CacheStationEnumType.JP.getDotno() - 1);
                    return;
                }

                //没有缓存机台用，去366
                toDot(agv, dot.getDotno(), 366);
                return;
            }
            return;
        } else if (data.getMountType() == AgvMountTypeEnum.UpFullAndDownEmpty) {
            //上满下空，BSG来的空花篮 去350
            toDot(agv, dot.getDotno(), 350);
        } else {
            MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。AGV下道工序：" + agv.getNextProcess());
        }
    }

    /**
     * 退火工序判断点，要么上料，要么接料
     * 或者去充电（低于70%）
     *
     * @param agv
     * @param data
     * @param dot
     */
    void d479(AgvBean agv, AgvDataBean data, DotBean dot) {
        if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
            if (data.getPower() < 70) {
                //去充电
                if (iPower.agvToPower(479, agv)) {
                    return;
                }
            }
            String process = "退火下料";
            boolean flag = findStationWithNoSpecial(dot, agv, process, false, TransDirectionEnum.OnlyOut);
            if (flag == false) {
                //空车去390
                //iAgvEvent.toRoad(agv, 161);
                agv.setNextProcess("BOE下料");
                iAgv.saveCache(agv);
                toDot(agv, 479, 392);
                return;
            }
        } else if (data.getMountType() == AgvMountTypeEnum.UpEmptyAndDownFull) {
            String process = "退火上料";
            if (agv.isFromHC()) {
                //来自缓存机
                boolean f = findStation(dot, agv, process, agv.getSpecialline(), TransDirectionEnum.OnlyIn);
                if (f == false) {
                    //原地不动
                }
            } else {
                //从popaid出来的
                boolean flag = findStation(dot, agv, process, agv.getSpecialline(), TransDirectionEnum.OnlyIn);
                if (flag == false) {
                    //找缓存机
                    flag = iStation.findCache(CacheStationEnumType.POPAID, agv.getAgvId(), true, true);
                    if (flag == false) {
                        //popaid1也没有找到 ,等

                    } else {
                        //去POPAID1
                        toDot(agv, dot.getDotno(), CacheStationEnumType.POPAID.getDotno() - 1);
                    }

                }
            }


        } else {
            MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。AGV下道工序：" + agv.getNextProcess());
        }
    }


    void d403(AgvBean agv, AgvDataBean data, DotBean dot) {
        if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
            agv.setNextProcess("退火下料");
            iAgv.saveCache(agv);
            toDot(agv, 403, 366);
        } else {
            if (iStation.stationCanUse(74, agv.getAgvId())) {
                iAgvEvent.toRoad(agv, 105);
            } else {
				/*
				if(iStation.stationCanUse(76, agv.getAgvId())) {
					iAgvEvent.toRoad(agv, 106);
				}else {
					MsgCore.sendMsg(agv.getAgvId(), "非空车不能移动");
				}
				*/
                //2号机台只要开启
                if (iStation.stationNotDisable(76)) {
                    //走411拐进去
                    iAgvEvent.toRoad(agv, 411);
                } else {
                    MsgCore.sendMsg(agv.getAgvId(), "非空车不能移动");
                }
            }
        }
    }


    /**
     * 如果是空车，则去BOE下料，或者451
     * 。如果是退火出来的，去BOE上料
     *
     * @param agv
     * @param data
     * @param dot
     */
    void d390(AgvBean agv, AgvDataBean data, DotBean dot) {
        if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
            if (data.getPower() < 70) {
                //充电
                if (iPower.agvToPower(392, agv)) {
                    return;
                }
            }

            String process = "BOE下料";
            boolean flag = findStationWithNoSpecial(dot, agv, process, false, TransDirectionEnum.OnlyOut);
            if (flag == false) {
                //去392
                toDot(agv, 390, 392);
                return;
            }

            //应该去空车直接去437
        } else if (data.getMountType() == AgvMountTypeEnum.UpEmptyAndDownFull) {
            if (agv.getNextProcess() != null && agv.getNextProcess().equals("BOE上料")) {
                String process = "BOE上料";
                findStation(dot, agv, process, agv.getSpecialline(), TransDirectionEnum.OnlyIn);
            } else {
                MsgCore.sendMsg(agv.getAgvId(), "AGV不应该出现在此处，当前工序：" + agv.getNextProcess());
            }
        } else {
            MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。AGV下道工序：" + agv.getNextProcess());
        }
    }


    /**
     * 与390相似，不考虑缓存机
     *
     * @param agv
     * @param data
     * @param dot
     */
    void d392(AgvBean agv, AgvDataBean data, DotBean dot) {
        DotBean dot390 = iDot.getBean(390);  //按390的点来做计算
        if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
            if (data.getPower() < 70) {
                //充电
                if (iPower.agvToPower(390, agv)) {
                    return;
                }
            }
            //
            if (agv.getNextProcess() != null && agv.getNextProcess().equals("BOE下料")) {
                String process = "BOE下料";
                //从390开始查
                boolean flag = findStationWithNoSpecial(dot390, agv, process, false, TransDirectionEnum.OnlyOut);
                if (flag == false) {
                    //去451 ，拿ALD的花篮
                    toDot(agv, dot390.getDotno(), 451);
                }
            } else {
                //BOE下料不可用，去退火下料
                if (iStation.hasEmpty("退火下料")) {
                    agv.setNextProcess("退火下料");
                    iAgv.saveCache(agv);
                    iAgvEvent.toRoad(agv, 155);
                } else {
					/*
					String  process= "BOE下料";
					//从390开始查
					boolean flag=findStationWithNoSpecial(dot390, agv, process, false, TransDirectionEnum.OnlyOut);
					if(flag==false) {
						//去451 ，拿ALD的花篮
						toDot(agv, dot390.getDotno(), 451);
					}
					*/

                    //直接去397
                    agv.setNextProcess("");
                    iAgv.saveCache(agv);
                    iAgvEvent.toRoad(agv, 155);
                }
                return;
            }
        } else if (data.getMountType() == AgvMountTypeEnum.UpEmptyAndDownFull) {
            if (agv.getNextProcess() != null) {
                String process = "BOE上料";
                boolean flag;
                if (agv.isFromHC()) {
                    //缓存机出来的
                    flag = findStation(dot390, agv, process, agv.getSpecialline(), TransDirectionEnum.OnlyIn);
                    if (flag == false) {
                        //没找到，等
                    }
                } else {
                    //从退火下料出来的
                    flag = findStation(dot390, agv, process, agv.getSpecialline(), TransDirectionEnum.OnlyIn);
                    if (flag == false) {
                        flag = iStation.findCache(CacheStationEnumType.TH, agv.getAgvId(), true, true);
                        if (flag == false) {
                            //缓存机不可用，等
                        } else {
                            toDot(agv, dot.getDotno(), CacheStationEnumType.TH.getDotno());
                        }
                    }
                }
            } else {
                MsgCore.sendMsg(agv.getAgvId(), "AGV不应该出现在此处，当前工序：" + agv.getNextProcess());
            }

        } else {
            MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。AGV下道工序：" + agv.getNextProcess());
        }
    }

    /**
     * 碱抛上空花篮判断点。如果是空车，去437
     *
     * @param agv
     * @param data
     * @param dot
     */
    void d397(AgvBean agv, AgvDataBean data, DotBean dot) {
        if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
            // 空车去437 ，让437做决策
            agv.setNextProcess("退火下料");
            iAgv.saveCache(agv);
            toDot(agv, dot.getDotno(), 437);
        } else if (data.getMountType() == AgvMountTypeEnum.UpFullAndDownEmpty) {
            String process = "碱抛上料";

            // 碱抛上料是空花篮，不需要线别
            boolean flag = findStationWithNoSpecial(dot, agv, process, true, TransDirectionEnum.OnlyIn);
            if (flag == false) {
                //机台不可用，找缓存机。缓存机不可用，走327
                boolean tocache = iStation.findCache(CacheStationEnumType.BSG, agv.getAgvId(), true, true);
                if (tocache) {
                    // 可以去缓存
                    toDot(agv, dot.getDotno(), CacheStationEnumType.BSG.getDotno());
                } else {
                    // 直接走105去碱抛上料
                    agv.setNextRoad(0);
                    agv.setNextProcess("去下一道工序");
                    agv.setNexttStationName("");
                    iAgv.saveCache(agv);
                    MsgCore.sendMsg(agv.getAgvId(), "需要卸载来自ALD的空花篮");
                    iAgvEvent.toRoad(agv, 327);
                }
            }
        } else {
            MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。AGV下道工序：" + agv.getNextProcess());

        }
    }


    /**
     * ALD湿法上料判断点，空车就去452
     *
     * @param agv
     * @param data
     * @param dot
     */
    void d451(AgvBean agv, AgvDataBean data, DotBean dot) {
        if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
            // 空车
            if (agv.getPower() < 50) {
                MsgCore.sendMsg(agv.getAgvId(), "去充电");
                toDot(agv, dot.getDotno(), 393);
                return;
            }
            //List<String> processList=Arrays.asList("ALD湿法","ALD干法","丝网");
            //去干法拿料
            List<String> processList = Arrays.asList("ALD干法");
            boolean flag = findStationWithNoSpecial(dot, agv, processList, false, TransDirectionEnum.OnlyOut);
            if (flag == false) {
                //空车，找不到就去充电
                // 入缓存机的判断 BMX,SW
                flag = iStation.findCache(CacheStationEnumType.BMX1, agv.getAgvId(), false, true);
                if (flag) {
                    // 去缓存
                    toDot(agv, dot.getDotno(), CacheStationEnumType.BMX1.getDotno() - 1);
                    return;
                }
                flag = iStation.findCache(CacheStationEnumType.BMX2, agv.getAgvId(), false, true);
                if (flag) {
                    // 去缓存
                    toDot(agv, dot.getDotno(), CacheStationEnumType.BMX2.getDotno() - 1);
                    return;
                }
                flag = iStation.findCache(CacheStationEnumType.SW, agv.getAgvId(), false, true);
                if (flag) {
                    // 去缓存
                    toDot(agv, dot.getDotno(), CacheStationEnumType.SW.getDotno() - 1);
                    return;
                }

                // 没有缓存机台可用的空车，去393
                toDot(agv, dot.getDotno(), 393);
            }
        } else if (data.getMountType() == AgvMountTypeEnum.UpEmptyAndDownFull) {
            if (agv.isFromHC() && agv.getNextProcess() != null && agv.getNextProcess().equals("丝网")) {
                //来自背膜下料的缓存机
                String process = "丝网";
                boolean flag = findStation(dot, agv, process, agv.getSpecialline(), TransDirectionEnum.OnlyIn);
                if (flag == false) {
                    //没机台，AGV不动
                }
            } else if (agv.isFromHC() && agv.getNextProcess() != null && agv.getNextProcess().equals("ALD湿法")) {
                //来自BOE下料的缓存
                String process = "ALD湿法";
                boolean flag = findStation(dot, agv, process, agv.getSpecialline(), TransDirectionEnum.OnlyIn);
                if (flag == false) {
                    //没机台，AGV不动
                }
            } else if (agv.isFromHC() && agv.getNextProcess() != null && agv.getNextProcess().equals("ALD干法")) {
                //来自BOE下料的缓存
                String process = "ALD干法";
                boolean flag = findStation(dot, agv, process, agv.getSpecialline(), TransDirectionEnum.OnlyIn);
                if (flag == false) {
                    //没机台，AGV不动
                }
            } else {
                String process = "ALD湿法";
                boolean flag = findStation(dot, agv, process, agv.getSpecialline(), TransDirectionEnum.OnlyIn);
                if (flag == false) {
                    //找BOE缓存1
                    flag = iStation.findCache(CacheStationEnumType.BOE1, agv.getAgvId(), true, true);
                    if (flag == false) {
                        //todo 去boe1缓存  ---> 现在去不了(报错:没有路线 缓存机没使用)
                        MsgCore.sendMsg(agv.getAgvId(), "等待中..");
                        //toDot(agv, dot.getDotno(), CacheStationEnumType.BOE1.getDotno() - 1);
                    }
                }
            }
        } else if (data.getMountType() == AgvMountTypeEnum.UpFullAndDownEmpty) {
            if (agv.getNextProcess().equals("碱抛上料")) {
                //去397
                toDot(agv, 452, 397);
            } else {
                MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息。当前工序：" + agv.getNextProcess());
            }
        } else {
            MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。当前工序：" + agv.getNextProcess());
        }
    }


    /**
     * 判断去缓存机还是去正膜上料。如果是空车，去正膜背膜下料拿料
     *
     * @param agv
     * @param data
     * @param dot
     */
    void d475(AgvBean agv, AgvDataBean data, DotBean dot) {

        if (data.getMountType() == AgvMountTypeEnum.UpEmptyAndDownFull) {
            String process = "正膜上料";
            findStation(dot, agv, process, agv.getSpecialline(), TransDirectionEnum.OnlyIn);
        } else if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
            //1。先找 ALD下料缓存和 正膜上料是否可用
			/*
			String process="正膜上料";
			boolean flag=iStation.hasEmpty(process);
			if(flag) {
				//有正膜上料的机台可用
				flag=iStation.findCache(CacheStationEnumType.ZMS, agv.getAgvId(), false,true);
				if(flag) {
					//ald下料（正膜上料）的缓存机可用
					toDot(agv, dot.getDotno(), CacheStationEnumType.ZMS.getDotno());
					return;
				}
			}

			//2。背膜上料 + 正膜下料缓存机台用
			process="背膜上料";
			flag=iStation.hasEmpty(process);
			if(flag) {
				//有背膜上料的机台可用
				flag=iStation.findCache(CacheStationEnumType.ZMX, agv.getAgvId(), false,true);
				if(flag) {
					//正膜下料的缓存机可用
					toDot(agv, dot.getDotno(), CacheStationEnumType.ZMX.getDotno());
					return;
				}
			}
			 */

            //机台下料选择
            List<String> processList = Arrays.asList("正膜下料", "背膜下料");
            boolean flag = findStationWithNoSpecial(dot, agv, processList, false, TransDirectionEnum.OnlyOut);
            if (flag == false) {

                //没有可用的机台，等待
                //MsgCore.sendMsg(agv.getAgvId(), "没有可用的机台，等待");
                //去476
                int road = iRoad.getNormalRoad(475, 476);
                if (road > 0) {
                    iAgvEvent.toRoad(agv, road);
                } else {
                    MsgCore.sendMsg(agv.getAgvId(), "没有可用的机台，等待");
                }
            }
        } else {
            MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。AGV下道工序：" + agv.getNextProcess());

        }
    }


    /**
     * 处理 76 78两个点
     *
     * @param agv
     * @param data
     * @param dot
     */
    void d729(AgvBean agv, AgvDataBean data, DotBean dot) {
        if (iStation.stationCanUse(76, agv.getAgvId())) {
            //76可用，走106
            iStation.lockStationOnTarget(76, agv.getAgvId());
            iAgvEvent.toRoad(agv, 106);
        } else if (iStation.stationCanUse(78, agv.getAgvId())) {
            //78可用，走107
            iStation.lockStationOnTarget(78, agv.getAgvId());
            iAgvEvent.toRoad(agv, 107);
        } else {
            MsgCore.sendMsg(agv.getAgvId(), "没有可用的机台，等待");
        }

    }


    /**
     * 镀膜出来的点
     *
     * @param agv
     * @param data
     * @param dot
     */
    void d476(AgvBean agv, AgvDataBean data, DotBean dot) {

        if (data.getMountType() == AgvMountTypeEnum.UpEmptyAndDownFull) {
            //上空下满，必须定线查找
            findStation(dot, agv, "丝网", agv.getSpecialline(), TransDirectionEnum.OnlyIn);
        } else if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {


            String process = "ALD干法";
            boolean flag = findStationWithNoSpecial(dot, agv, process, false, TransDirectionEnum.OnlyOut);
            if (flag == false) {
                //ALD干法没有可用的机台
                //1。如果丝网+背膜下料缓存可用
                flag = iStation.hasEmpty(process);
                if (flag) {
                    //丝网有空位
                    boolean c1 = iStation.findCache(CacheStationEnumType.BMX1, agv.getAgvId(), false, true);
                    if (c1) {
                        //缓存机1出料可用
                        toDot(agv, dot.getDotno(), CacheStationEnumType.BMX1.getDotno() - 1);
                        return;
                    } else {
                        c1 = iStation.findCache(CacheStationEnumType.BMX2, agv.getAgvId(), false, true);
                        if (c1) {
                            //缓存机2出料可用
                            toDot(agv, dot.getDotno(), CacheStationEnumType.BMX2.getDotno() - 1);
                            return;
                        }
                    }
                }
                //2.ALD湿法有位子+BOE下料缓存可用
                process = "ALD湿法";
                flag = iStation.hasEmpty(process);
                if (flag) {
                    // BOE1有空位
                    boolean c1 = iStation.findCache(CacheStationEnumType.BOE1, agv.getAgvId(), false, true);
                    if (c1) {
                        // 缓存机1出料可用
                        toDot(agv, dot.getDotno(), CacheStationEnumType.BOE1.getDotno() - 1);
                        return;
                    }
                }

                //3.popaid2号机（靠BOE）+退火上料
                process = "退火上料";
                flag = iStation.hasEmpty(process);
                if (flag) {
                    // BOE1有空位
                    boolean c1 = iStation.findCache(CacheStationEnumType.TH, agv.getAgvId(), false, true);
                    if (c1) {
                        // 退火出料可用
                        toDot(agv, dot.getDotno(), CacheStationEnumType.TH.getDotno() - 1);
                        return;
                    }
                }

                //去452
                toDot(agv, 476, 452);
            } else {
                //有机台可用，不处理
            }

        } else {
            MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。当前工序：" + agv.getNextProcess());

        }
    }


    /**
     * 制绒下料充电
     *
     * @param agv
     */
    void p364(AgvBean agv, DotBean dot) {
        if (agv.getPower() < 70) {
            if (iPower.agvToPower(364, agv)) {
                return;
            }
        }

        StationGroupDao gbean = iStation.fetchNextOutStation(364, agv.getAgvId(), "制绒下料", true);
        if (gbean != null) {
            //去366
            toDot(agv, 364, 366);
        } else {
            //增量逻辑之前是等待制绒下料机台  现在寻找待命点
            //增量逻辑之前是寻找上料点  现在去往待命点

            MsgCore.sendMsg(agv.getAgvId(), "寻找制绒待命点");
            //查看是否有待命点
            //todo 定死的制绒区域待命点 后续需改为按类型匹配待命点
            String dotid = dmdUtils.checkDmdbyZrs(agv.getAgvId());
            //有待命点则去待命点
            if (dotid != null) {
                toDot(agv, dot.getDotno(), Integer.parseInt(dotid));
                MsgCore.sendMsg(agv.getAgvId(), "去往制绒上料待命点：" + dotid);
                //给待命点加锁
                dmdUtils.lockDmd(agv.getAgvId() + "", dotid);
            }


        }


    }


    /**
     * 发料小车专用充电
     *
     * @param agv
     */
    void p363(AgvBean agv) {
        if (agv.getAgvId() == 19 || agv.getAgvId() == 20) {
            if (agv.getPower() < 70) {
                if (iPower.agvToPower(363, agv)) {
                    return;
                }
            }
            toDot(agv, 363, 201);
        } else {
            MsgCore.sendMsg(agv.getAgvId(), "非发料AGV不应该停在此处");
        }
    }


    /**
     * 分支点
     *
     * @param agv
     * @param amount
     */
    void p452(AgvBean agv, AgvDataBean amount) {
        if (amount.getMountType() == AgvMountTypeEnum.AllEmpty) {
            //空车和上空下满去393
            if (amount.getPower() < 70) {
                //去充电
                if (iPower.agvToPower(452, agv)) {
                    return;
                }
                //452没位置了，去中间
                toDot(agv, 452, 393);
            } else {
                //去397，那边安排 去退火
                //进入5台缓存机的判断
                boolean flag = iStation.findCache(CacheStationEnumType.BMX1, agv.getAgvId(), false, true);
                if (flag) {
                    toDot(agv, 452, CacheStationEnumType.BMX1.getDotno() - 1);
                    return;
                }
                flag = iStation.findCache(CacheStationEnumType.BMX2, agv.getAgvId(), false, true);
                if (flag) {
                    toDot(agv, 452, CacheStationEnumType.BMX2.getDotno() - 1);
                    return;
                }
                flag = iStation.findCache(CacheStationEnumType.SW, agv.getAgvId(), false, true);
                if (flag) {
                    toDot(agv, 452, CacheStationEnumType.SW.getDotno() - 1);
                    return;
                }
                flag = iStation.findCache(CacheStationEnumType.BOE1, agv.getAgvId(), false, true);
                if (flag) {
                    toDot(agv, 452, CacheStationEnumType.BOE1.getDotno() - 1);
                    return;
                }

                //没有可用的缓存，去397
                toDot(agv, 452, 397);
            }
        } else if (amount.getMountType() == AgvMountTypeEnum.UpEmptyAndDownFull) {
            toDot(agv, 452, 393);
        } else if (amount.getMountType() == AgvMountTypeEnum.UpFullAndDownEmpty) {
            //上满下空
            if (agv.getNextProcess().equals("碱抛上料")) {
                toDot(agv, 452, 397);
            } else {
                MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。当前工序：" + agv.getNextProcess());
            }
        } else {
            MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。当前工序：" + agv.getNextProcess());
        }
    }


    /**
     * 镀膜充电
     *
     * @param agv
     * @param amount
     */
    void p393(AgvBean agv, AgvDataBean amount) {
        if (amount.getMountType() == AgvMountTypeEnum.AllEmpty) {
            if (agv.getPower() < 80) {
                if (iPower.agvToPower(393, agv)) {

                } else {
                    MsgCore.sendMsg(agv.getAgvId(), "电量不足，AGV无法胜任工作");
                }
                return;
            }
            boolean flag = iStation.hasEmpty(Arrays.asList("正膜下料", "背膜下料"));
            if (flag == false) {
                //没有可用的下料机台，也去充电
                if (iPower.agvToPower(393, agv)) {
                    return;
                }
            }
            //去475，走137
            toDot(agv, 393, 475);
        } else if (amount.getMountType() == AgvMountTypeEnum.UpEmptyAndDownFull) {

            //todo 带料充电  --> 会带ald的料去正膜的料
            String process = "正膜上料";
            StationGroupDao gbean = iStation.fetchNextInStation(393, agv.getAgvId(), process, 0, true);
            if (gbean != null) {
                //正膜上料有需求 去475
                toDot(agv, 393, 475);
            } else {
                //没有可用的上料机台，也去充电
                if (iPower.agvToPower(393, agv)) {
                    MsgCore.sendMsg(agv.getAgvId(), "去充电，下道工序:" + agv.getNextProcess());
                    return;
                }

                //没充电装 去475
                toDot(agv, 393, 475);
            }

        } else {
            MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。AGV下道工序：" + agv.getNextProcess());
        }
    }

    void d518(AgvBean agv, AgvDataBean data, DotBean dot) {
        if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
            //1。先找 ALD下料缓存和 正膜上料是否可用
            String process = "碱抛下料";
            boolean flag = findStationWithNoSpecial(dot, agv, process, false, TransDirectionEnum.OnlyOut);
            if (flag == false) {
                //去406，走256
                agv.setNextProcess("碱抛下料");
                iAgv.saveCache(agv);
                iAgvEvent.toRoad(agv, 256);
            }
        } else {
            MsgCore.sendMsg(agv.getAgvId(), "只有空车能移动");

        }
    }


    void d477(AgvBean agv, AgvDataBean data, DotBean dot) {
        if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
            // 空车，走164，去452
            iAgvEvent.toRoad(agv, 164);
        } else if (data.getMountType() == AgvMountTypeEnum.UpEmptyAndDownFull) {
            if (agv.isFromHC()) {
                // 只能去ALD干法
                boolean flag = findStationWithNoSpecial(dot, agv, "ALD干法", true, TransDirectionEnum.OnlyIn);
                if (flag == false) {
                    // 等
                }
            } else {
                MsgCore.sendMsg(agv.getAgvId(), "缓存机卸料专用点位，请人工处理");
            }
        } else {
            MsgCore.sendMsg(agv.getAgvId(), "只有空车能移动");

        }
    }

}
